
/*
 * ppdHandler.c
 *
 *  Created on: 01/10/2011
 *      Author: utn_so
 */

#include "ppdHandler.h"
#include <stdio.h>
#include <stdlib.h>
    void atenderPPD(void *arg)
    {
    	stPedido *pedido;
    	stNodoPedido *resultado;
    	int32_t total=0;
        stDatosPPD *datosPPD = (stDatosPPD *)arg;
        PAQUETE_NIPC_CABECERA *cabecera = (PAQUETE_NIPC_CABECERA*)malloc(sizeof(PAQUETE_NIPC_CABECERA));
        int32_t nbytes;
        for(;;) {


			// gestionar datos de un cliente
			if ((nbytes = recv(datosPPD->disco->socket, cabecera, sizeof(PAQUETE_NIPC_CABECERA), MSG_WAITALL)) <= 0) {
				// error o conexión cerrada por el cliente
				if (nbytes == 0) {
					// conexión cerrada
					printf("hang up ppd %d\n",datosPPD->disco->id);
					//pthread_mutex_lock(datosPPD->semaforo);
					Redistribuir(datosPPD->disco->socket,datosPPD->semaforo);
					//pthread_mutex_unlock(datosPPD->semaforo);
					return;


				} else {
					//error en el recv
					printf("error recv \n");
					//pthread_mutex_lock(datosPPD->semaforo);
					Redistribuir(datosPPD->disco->socket,datosPPD->semaforo);
					//pthread_mutex_unlock(datosPPD->semaforo);
					return;
				}
			} else {
				if (nbytes < sizeof(PAQUETE_NIPC_CABECERA))
				{
					printf("recibi menos CABCERA\n");
				}
				// tenemos datos de algún cliente
				//ACA VA NUESTRA LOGICA EN BASE A LO QUE RECIBAMOS DEL PROTOCOLO NIPC

				//printf("hilo %d \n",datosPPD->disco->threadId);
				switch(cabecera->type)
				{
					case LEER:
					case ESCRIBIR:
//TODO vERRR
						pedido = recibirDeSocket(datosPPD->disco->socket,cabecera,&total);
						pthread_mutex_lock(datosPPD->semaforo);
						//REGIO resultado = sacarNodoListaPedidos(pedido,&datosPPD->disco->listaPedidos);
						sacarNodoListaPedidos2(pedido,&datosPPD->disco->listaPedidos);
						datosPPD->disco->cantidadPedidos = datosPPD->disco->cantidadPedidos - 1;
						pthread_mutex_unlock(datosPPD->semaforo);

						int32_t payloadlength = sizeof(stPedido);
						char *mensaje = malloc(payloadlength);
						memcpy(mensaje,pedido,payloadlength);


						char *paq = serializarNipc(pedido->tipoOperacion,mensaje,payloadlength);

						send(pedido->socketPFS,paq,sizeof(PAQUETE_NIPC_CABECERA) + payloadlength, 0);

						//free(resultado);REGIO
						free(paq);
						free(mensaje);
						free(pedido);

						break;
					case SINCROLEERRESPUESTA:


						pedido = recibirDeSocket(datosPPD->disco->socket,
								cabecera,&total);
						if (total < sizeof(stPedido))
						{
							printf("menos sincro leer respuesta\n");
						}
						//pedido->tipoOperacion = SINCROLEER; CAMBIO REGIO
//			BUG			pthread_mutex_lock(datosPPD->disco->semaforoInterno);
	//					datosPPD->disco->cantidadPedidos = datosPPD->disco->cantidadPedidos - 1;
						//resultado = sacarNodoListaPedidos(pedido,&datosPPD->disco->listaPedidos); CAMBIO REGIO
		//				pthread_mutex_unlock(datosPPD->disco->semaforoInterno);

						AgregarEscrituraSincronizacion(pedido,datosPPD->semaforo);

						//free(resultado);CAMBIO REGIO
						free(pedido);//CAMBIO REGIO
						break;
					case SINCROESCRIBIRRESPUESTA:

						pedido = recibirDeSocket(datosPPD->disco->socket,cabecera,&total);

						//pthread_mutex_lock(datosPPD->disco->semaforoInterno);
						//pedido->tipoOperacion = SINCROESCRIBIR; //esto es para cuando compara en el sacar nodo lista
						//resultado = sacarNodoListaPedidos(pedido,&datosPPD->disco->listaPedidos);
						//pthread_mutex_unlock(datosPPD->disco->semaforoInterno);
						//free(resultado);
						free(pedido); //CAMBIO REGIO
						break;
					case SINCROCOMPLETA:

						datosPPD->disco->discoSincronizado = 1;
						//HabilitarDisco(datosPPD->disco->socket,datosPPD);

						char *fechayhora = (char*)malloc(12);
						time_t hora = time(NULL);
						struct tm *tmPtr = localtime(&hora);
						strftime( fechayhora, 10, "%H:%M:%S", tmPtr );

						printf("sincronizacion completa hora inicio: %s hora fin: %s \n",datosPPD->horacInicioSincro,fechayhora);
						free(fechayhora);
						free(datosPPD->horacInicioSincro);

						break;
					case SINCROSEMICOMPLETA:
						if (cantDiscosConectados() > 1 && datosPPD->disco->discoSincronizado != 1)
						{
							//ver el disco al q todavia no le pedi nada y mandarle que quiero los impares
							stPedido *pedido = (stPedido*)malloc(sizeof(stPedido));
							pedido->sector = 0;
							pedido->socketPFS = datosPPD->disco->socket;
							pedido->tipoOperacion = SINCROLEERIMPARES;
							payloadlength = sizeof(stPedido);
							char *mensaje2 = malloc(payloadlength);

							memcpy(mensaje2,pedido,sizeof(stPedido));
							char *paq2 = serializarNipc(pedido->tipoOperacion,mensaje2,payloadlength);
							int32_t nbytes2 = send(datosPPD->disco->discoSincronizado,paq2,sizeof(PAQUETE_NIPC_CABECERA) + payloadlength, 0);


							free(pedido);
							free(paq2);

						}
						break;
					case PAYFALLO:
						printf("PAYFALLO\nPAYFALLO\n");
						break;
					case PAYOK:
						//printf("payok\npayok\n");
					case TAMANIODISCO:

						break;
					default:
						printf("es para regio q lo mira por tv %u\n",cabecera->type);
						break;

				}

			}
		}
    }



